package com.storydo.db.view.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.concurrent.CopyOnWriteArrayList;

import lombok.extern.slf4j.Slf4j;

/**   
* @Title: LocaleUtils.java 
* @Description: 语言切换
* @author : Storydo
* @date: 2021年9月15日 下午3:21:24 
* @version:V1.0 
* Copyright 悦享互联 2016 All right reserved.
* Modification  History:
* Version       Date          Author          Description
* ----------------------------------------------------------------------------
*  1.0         2021年9月15日        Storydo              TODO
*/
@Slf4j
public class LocaleUtils {

	public static final String RES_KEY_PFX = "[res_key=";
	
	private static final String propsFile = "./config.properties";
	
	private static volatile Properties appProperties;

	private static final CopyOnWriteArrayList<LocaleChangeListener> localeChangeListeners = new CopyOnWriteArrayList<>();

	private static volatile Locale locale;
	
	
	public static Properties getProperties() {
		if (appProperties == null) {
			loadProperties(propsFile);
		}
        return appProperties;
    }
	
	public static void loadProperties(String file) {
        Properties p = new Properties(System.getProperties());
        try (InputStream is = new FileInputStream(new File(file))) {
            p.load(is);
        } catch (IOException e) {
            try (InputStream is = ClassLoader.getSystemResourceAsStream(
                        "config/dbview.properties")) { // $NON-NLS-1$
                if (is == null) {
                    throw new RuntimeException("Could not read properties file:" + file);
                }
                p.load(is);
            } catch (IOException ex) {
                throw new RuntimeException("Could not read properties file:" + file);
            }
        }
        appProperties = p;
    }

	public static String getResString(String key) {
        return getResStringDefault(key, RES_KEY_PFX + key + "]"); // $NON-NLS-1$
    }
	
	private static String getResStringDefault(String key, String defaultValue) {
        if (key == null) {
            return null;
        }
        // Resource keys cannot contain spaces, and are forced to lower case
        String resKey = key.replace(' ', '_'); // $NON-NLS-1$ // $NON-NLS-2$
        resKey = resKey.toLowerCase(java.util.Locale.ENGLISH);
        String resString = null;
        try {
            ResourceBundle bundle = getBundle(getLocale());

            if (bundle.containsKey(resKey)) {
                resString = bundle.getString(resKey);
            } else {
                if(defaultValue == null) {
                    log.warn("ERROR! Resource string not found: [{}]", resKey);
                } else {
                    log.debug("Resource string not found: [{}], using default value {}", resKey, defaultValue);
                }
                resString = defaultValue;
            }
        } catch (MissingResourceException mre) { // NOSONAR We handle correctly exception
           
            if(defaultValue == null) {
                log.warn("ERROR! Resource string not found: [{}]", resKey);
            } else {
                log.debug("Resource string not found: [{}], using default value {}", resKey, defaultValue);
            }
            resString = defaultValue;
        }
        return resString;
    }
	
	public static void setProperty(String key, String props) {
		appProperties.setProperty(key, props);
		try (OutputStream out = new FileOutputStream(new File(propsFile))) {
            appProperties.store(out, "系统配置");
        } catch (IOException e) {
            log.error(e.getMessage(), e);
        }
	}
	
	public static Locale getLocale() {
		if (locale == null) {
			String localeLanguage = getProperties().getProperty("dbview.sys.locale");
			if (localeLanguage == null) {
				locale = Locale.getDefault();
			} else {
				locale = new Locale(localeLanguage);
			}
		}
        return locale;
    }
	
	public static void setLocale(Locale loc) {
        log.info("Setting Locale to {}", loc);
        
        notifyLocaleChangeListeners();
       
        setProperty("dbview.sys.locale", loc.getLanguage());
        
    }
	
	private static ResourceBundle getBundle(Locale forcedLocale) {
        for (Locale locale: Arrays.asList(forcedLocale, getLocale())) {
            if(locale != null) {
                ResourceBundle bundle = ResourceBundle.getBundle("config.message.messages", locale); // $NON-NLS-1$
                if (bundle == null) {
                    log.warn("Could not resolve ResourceBundle for Locale [{}]", locale);
                } else {
                    return bundle;
                }
            }
        }
        return new DummyResourceBundle();
    }
	
	private static void notifyLocaleChangeListeners() {
		LocaleChangeEvent event = new LocaleChangeEvent(LocaleUtils.class, locale);
		for (LocaleChangeListener listener : localeChangeListeners) {
			listener.localeChanged(event);
		}
	}
	
	public static void addLocaleChangeListener(LocaleChangeListener listener) {
        localeChangeListeners.add(listener);
    }

    public static void removeLocaleChangeListener(LocaleChangeListener listener) {
        localeChangeListeners.remove(listener);
    }
	
	private static class DummyResourceBundle extends ResourceBundle {

		@Override
		protected Object handleGetObject(String key) {
			return "[" + key + "]";
		}

		@Override
		public Enumeration<String> getKeys() {
			return Collections.emptyEnumeration();
		}
	};

}
